package com.xinsoft.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinsoft.common.exception.BDException;
import com.xinsoft.constant.Const;
import com.xinsoft.entity.dto.CusTaskDTO;
import com.xinsoft.entity.dto.CusTaskParam;
import com.xinsoft.entity.po.*;
import com.xinsoft.entity.vo.*;
import com.xinsoft.mapper.CusTaskApproveMapper;
import com.xinsoft.mapper.CusTaskDealMapper;
import com.xinsoft.service.*;
import com.xinsoft.mapper.CusTaskMapper;
import com.xinsoft.utils.TokenUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author ZYM
 * @description 针对表【cus_task(任务主表)】的数据库操作Service实现
 * @createDate 2023-07-31 14:00:37
 */
@Service
public class CusTaskServiceImpl extends ServiceImpl<CusTaskMapper, CusTask>
        implements CusTaskService {
    @Resource
    private CusTaskDealMapper taskDealMapper;
    @Resource
    private CusTaskApproveMapper taskApproveMapper;
    @Autowired
    private CusDocumentService documentService;
    @Autowired
    private SysFileHisService fileHisService;
    @Autowired
    private CusTaskDealService taskDealService;
    @Autowired
    private CusTaskApproveService taskApproveService;
    @Autowired
    private SysDocumentNumService documentNumService;

    @Override
    public IPage<CusTaskPageVo> findPageListByParam(CusTaskParam param) {
        param.setCurrentUserId(TokenUtil.getUserId());
        Page<CusTaskPageVo> page = new Page<>(param.getCurrentPage(), param.getPageSize());
        IPage<CusTaskPageVo> pageList = baseMapper.findPageListByParam(page, param);
        return pageList;
    }

    @Override
    public CusTask tempSave(CusTaskDTO dto) {
        CusTask task = new CusTask();
        BeanUtils.copyProperties(dto, task);
        task.setTaskStatus(Const.TaskStatus.STAGING);
        if (Objects.isNull(task.getId())) {
            // 更新流水号
            this.serialNumber(task.getTaskType());
            this.save(task);
        } else {
            documentService.remove(Wrappers.lambdaQuery(CusDocument.class).eq(CusDocument::getDeviceRefId, task.getId()));
            this.updateById(task);
        }

        // 保存附件关系
        List<SysFileHis> fileHisList = dto.getSysFileHisList();
        List<CusDocument> documentList = new ArrayList<>();
        fileHisList.forEach(fileHis -> {
            CusDocument document = new CusDocument();
            document.setDocumentId(fileHis.getId());
            document.setDeviceRefId(task.getId());
            document.setDeviceRefType(Const.DeviceRefType.TASK_FILE);
            documentList.add(document);
        });
        documentService.saveBatch(documentList);
        return task;
    }

    public void serialNumber(Integer taskType) {
        switch (taskType) {
            case 10337:
                // 日常事件
                documentNumService.incrementLastSerialByDocumentId(Const.DOCUMENT_ID.EVERYDAY_INCIDENTS_DOCUMENT);
                break;
            case 10339:
                // 生产事件
                documentNumService.incrementLastSerialByDocumentId(Const.DOCUMENT_ID.PRODUCTION_EVENTS_DOCUMENT);
                break;
            case 10341:
                // 质量事件
                documentNumService.incrementLastSerialByDocumentId(Const.DOCUMENT_ID.QUALITY_EVENTS_DOCUMENT);
                break;
            case 10343:
                // 8D报告
                documentNumService.incrementLastSerialByDocumentId(Const.DOCUMENT_ID.REPORT_DOCUMENT);
                break;
        }
    }

    @Override
    public CusTaskVo detail(Integer id) {
        CusTaskVo vo = baseMapper.getTaskById(id);
        vo.setCusTaskDealList(taskDealMapper.listByTaskId(id));
        List<CusDocument> documentList = documentService.list(Wrappers.lambdaQuery(CusDocument.class)
                .eq(CusDocument::getDeviceRefId, id)
                .eq(CusDocument::getDeviceRefType, Const.DeviceRefType.TASK_FILE));
        if (!documentList.isEmpty()) {
            List<Integer> documentIds = documentList.stream().map(CusDocument::getDocumentId).collect(Collectors.toList());
            vo.setSysFileHisList(fileHisService.listByIds(documentIds));
        }
        return vo;
    }

    @Override
    public void del(List<Integer> ids) {
        List<CusTask> list = this.list(Wrappers.lambdaQuery(CusTask.class)
                .eq(CusTask::getTaskStatus, Const.TaskStatus.STAGING)
                .in(CusTask::getId, ids));
        if (list.size() < ids.size()) {
            throw new BDException("单据已提交，不可以删除！");
        }
        this.removeByIds(ids);
        //删除附件关系
        documentService.remove(Wrappers.lambdaQuery(CusDocument.class)
                .eq(CusDocument::getDeviceRefType, Const.DeviceRefType.TASK_FILE)
                .in(CusDocument::getDeviceRefId, ids));
    }

    @Override
    public void submit(CusTaskDTO dto) {
        CusTask task = this.tempSave(dto);
        // 更新任务状态为待处理
        this.update(Wrappers.lambdaUpdate(CusTask.class)
                .eq(CusTask::getId, task.getId())
                .set(CusTask::getTaskStatus, Const.TaskStatus.PENDING));
        // 新增一条处理记录，处理人id默认为任务的责任人
        CusTaskDeal taskDeal = new CusTaskDeal();
        taskDeal.setTaskId(task.getId());
        taskDeal.setDealStatus(Const.TaskDealStatus.TRANSFERRED);
        taskDeal.setDealPersonId(task.getDutyPersonId());
        taskDealService.save(taskDeal);
    }

    @Override
    public void dealTS(CusTaskDeal taskDeal) {
        this.checkDeal(taskDeal);
        taskDeal.setDealStatus(Const.TaskDealStatus.PROCESSING);
        taskDeal.setDealPersonId(TokenUtil.getUserId());
        if (Objects.isNull(taskDeal.getId())) {
            taskDealService.save(taskDeal);
        } else {
            taskDealService.updateById(taskDeal);
        }
    }

    @Override
    public void dealSubmit(CusTaskDeal taskDeal) {
        this.checkDeal(taskDeal);
        // 任务处理状态为已完成
        taskDeal.setDealStatus(Const.TaskDealStatus.COMPLETED);
        taskDeal.setDealPersonId(TokenUtil.getUserId());
        if (Objects.isNull(taskDeal.getId())) {
            taskDealService.save(taskDeal);
        } else {
            taskDealService.updateById(taskDeal);
        }
        // 更新任务状态为待验收
        this.update(Wrappers.lambdaUpdate(CusTask.class)
                .eq(CusTask::getId, taskDeal.getTaskId())
                .set(CusTask::getTaskStatus, Const.TaskStatus.WAIT_ACCEPTANCE));
    }

    public void checkDeal(CusTaskDeal taskDeal) {
        CusTask task = this.getById(taskDeal.getTaskId());
        if (!Const.TaskStatus.PENDING.equals(task.getTaskStatus())) {
            throw new BDException("不是待处理状态下的任务，不能进行处理");
        }
        List<CusTaskDeal> taskDealList = taskDealService.list(Wrappers.lambdaQuery(CusTaskDeal.class)
                .eq(CusTaskDeal::getTaskId, taskDeal.getTaskId())
                .eq(CusTaskDeal::getDealStatus, Const.TaskDealStatus.TRANSFERRED)
                .orderByDesc(CusTaskDeal::getId));
        if (taskDealList.size() > 0 && !taskDealList.get(0).getDealPersonId().equals(TokenUtil.getUserId())) {
            throw new BDException("不是任务处理人，不能进行处理");
        }
    }

    @Override
    public void acceptanceTS(CusTaskApprove cusTaskApprove) {
        CusTask task = this.getById(cusTaskApprove.getTaskId());
        if (!Const.TaskStatus.WAIT_ACCEPTANCE.equals(task.getTaskStatus())) {
            throw new BDException("不是待验收状态下的任务，不能进行验收");
        }
        if (!TokenUtil.getUserId().equals(task.getCreateBy())) {
            throw new BDException("不是任务创建人，不能进行验收");
        }
        if (Objects.isNull(cusTaskApprove.getId())) {
            taskApproveService.save(cusTaskApprove);
        } else {
            taskApproveService.updateById(cusTaskApprove);
        }
    }

    @Override
    public void acceptanceSubmit(CusTaskApprove cusTaskApprove) {
        List<CusTaskDeal> taskDealList = taskDealService.list(Wrappers.lambdaQuery(CusTaskDeal.class)
                .eq(CusTaskDeal::getTaskId, cusTaskApprove.getTaskId())
                .orderByDesc(CusTaskDeal::getId));
        CusTaskDeal cusTaskDeal = taskDealList.get(0);
        // 保存验收结果
        cusTaskApprove.setApprovePersonId(TokenUtil.getUserId());
        cusTaskApprove.setApproveTime(new Date());
        cusTaskApprove.setTaskDealId(cusTaskDeal.getId());
        this.acceptanceTS(cusTaskApprove);
        // 更新任务状态
        if (cusTaskApprove.getApproveResult().equals(Const.TaskAcceptanceResult.RESULT_PASS)) {
            // 通过，任务状态改为已验收
            this.update(Wrappers.lambdaUpdate(CusTask.class)
                    .eq(CusTask::getId, cusTaskApprove.getTaskId())
                    .set(CusTask::getTaskStatus, Const.TaskStatus.ACCEPTED));
            // 任务处理状态改为通过
            cusTaskDeal.setDealStatus(Const.TaskDealStatus.PASSED);
            taskDealService.updateById(cusTaskDeal);
        }
        if (cusTaskApprove.getApproveResult().equals(Const.TaskAcceptanceResult.RESULT_UNPASS)) {
            // 不通过，任务状态改为待处理
            this.update(Wrappers.lambdaUpdate(CusTask.class)
                    .eq(CusTask::getId, cusTaskApprove.getTaskId())
                    .set(CusTask::getTaskStatus, Const.TaskStatus.PENDING));
            // 任务处理状态改为已退回
            cusTaskDeal.setDealStatus(Const.TaskDealStatus.ROLLEDBACK);
            taskDealService.updateById(cusTaskDeal);
        }
    }

    @Override
    public void transfer(Integer taskId, Integer userId) {
        CusTask task = this.getById(taskId);
        if (!task.getTaskStatus().equals(Const.TaskStatus.PENDING)) {
            throw new BDException("不是待处理状态下的任务，不能进行转派");
        }
        if (!task.getDutyPersonId().equals(TokenUtil.getUserId())) {
            throw new BDException("不是任务责任人，不能进行转派");
        }
        // 新增一条处理记录，处理人id默认为任务的责任人
        CusTaskDeal taskDeal = new CusTaskDeal();
        taskDeal.setTaskId(taskId);
        taskDeal.setDealStatus(Const.TaskDealStatus.TRANSFERRED);
        taskDeal.setDealPersonId(userId);
        taskDealService.save(taskDeal);

    }

    @Override
    public CusTaskDealDetailVo dealDetail(Integer taskDealId) {
        CusTaskDealDetailVo vo = new CusTaskDealDetailVo();
        vo.setCusTaskDeal(taskDealMapper.getById(taskDealId));
        vo.setCusTaskApprove(taskApproveMapper.getByTaskDealId(taskDealId));
        return vo;
    }

    @Override
    public CusTaskDealVo getNewestDealTS(Integer taskId) {
        CusTaskDealVo vo = new CusTaskDealVo();
        List<CusTaskDealVo> list = taskDealMapper.listByTaskId(taskId);
        if (list.size() > 0 && list.get(0).getDealStatus().equals(Const.TaskDealStatus.PROCESSING)) {
            vo = list.get(0);
        }
        return vo;
    }

    @Override
    public CusTaskApproveVo getAcceptanceTS(Integer taskId) {
        return taskApproveMapper.getByTaskId(taskId);
    }
}




